package com.lifesting.front;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.event.PhaseId;

import com.sun.faces.renderkit.RenderKitUtils;
import com.sun.faces.renderkit.html_basic.HtmlBasicRenderer;

public class DataScrollerRender extends HtmlBasicRenderer {
	public static final String RENDER_TYPE = "com.lifesting.render.datasroller";
	private int getColumnsCount(Table t) {
		List<UIComponent> columns = t.getChildren();
		int i = 0;
		for (Iterator<UIComponent> ite = columns.iterator(); ite.hasNext();)
		{
			if (ite.next() instanceof Column)
			{
				++i;
			}
		}
		if (t.getRowsCheckable())
		{
			++i; //增加一个隐含的列
		}
		return i;
	}
	@Override
	public void encodeBegin(FacesContext context, UIComponent component)
			throws IOException {
		super.encodeBegin(context, component);
		assert (component instanceof DataScroller);
		DataScroller ds = (DataScroller) component;
		String specified_table = ds.getTableFor();
		
		ResponseWriter writer = context.getResponseWriter();
		if (specified_table == null)
			writer.startElement("tr", component);
		else
		{
			writer.startElement("p", component);
			writer.writeAttribute("align", "center", null);
		}
		String id = component.getClientId(context);
		writer.writeAttribute("id", id, "id");
		
		Table table = findTableFor(context,component);
		if (table == null)
			throw new IOException("DS must be in MyTable");
		if (specified_table == null)
		{
			writer.startElement("td", component);
			writer.writeAttribute("colspan", getColumnsCount(table), null);
			writer.writeAttribute("align", "center", null);
		}
		writer.write("共有 "+table.getTotalCount()+" 条符合条件记录");
		RenderKitUtils.renderFormInitScript(writer, context);
		writer.write("| ");
		Integer cp = table.getCurrentPage();
		
		writeCommandLink(context,component,"首页",id+".1");
		writer.write("| ");
		if (cp > 1)
			writeCommandLink(context,component,"上页",id+".2");
		else
			writer.write("上页");
		writer.write("| ");
		if (cp < table.getTotalPages())
			writeCommandLink(context,component,"下页",id+".3");
		else
			writer.write("下页");
		writer.write("| ");
		writeCommandLink(context,component,"尾页",id+".4");
		writer.write("| 页次 "); //.5
		//page input .6
		writer.startElement("input", component);
		writer.writeAttribute("id", id+".6", null );
		writer.writeAttribute("name", id+".6", null);
		writer.writeAttribute("type", "text", null);
		writer.writeAttribute("size", String.valueOf(table.getTotalPages()).length()+1, null);
		writer.writeAttribute("value", table.getCurrentPage(), null);
		writer.endElement("input");
		writer.write("/ "+table.getTotalPages()+" ");
		//jump to the input page .7
		writer.startElement("input", component);
		writer.writeAttribute("id", id+".7", null);
		writer.writeAttribute("name", id+".7", null);
		writer.writeAttribute("type", "submit", null);
		writer.writeAttribute("value", "跳转", null);
		writer.endElement("input");
	}
	static final Param[] EMPTY_PARAMS = new Param[0];
	private void writeCommandLink(FacesContext context, UIComponent component, String dis_text, String cid) throws IOException {
		ResponseWriter writer = context.getResponseWriter();
		writer.startElement("a", component);
		writer.writeAttribute("href", "#", null);
		String form_client_id= getFormId(component,context);
		writer.writeAttribute("onclick",RenderKitUtils.getCommandLinkOnClickScript(form_client_id, 
				cid, "", EMPTY_PARAMS), "onclick");
		writer.write(dis_text);
		writer.endElement("a");
	}
	@Override
	public void decode(FacesContext context, UIComponent component) {
		//检测到底是那个 first/previous/next/last/input 1/2/3/4/7
		Integer page = -1;
		Table table;
		table = findTableFor(context, component);
		String ds_id = component.getClientId(context);
		Map<String,String> rpm =
            context.getExternalContext().getRequestParameterMap();
		if (rpm.containsKey(ds_id+".1")){
			page = 1;
		}
		else if(rpm.containsKey(ds_id+".2")){
			page = table.getCurrentPage()-1;
		}
		else if(rpm.containsKey(ds_id+".3")){
			page = table.getCurrentPage()+1;
		}
		else if (rpm.containsKey(ds_id+".4")){
			page = table.getTotalPages();
		}
		else if (rpm.containsKey(ds_id+".7"))
		{
			//用户点击了跳转，从.6从查询到底是那一页
			Integer input_page = Integer.valueOf(rpm.get(ds_id+".6"));
			if (input_page <1 || input_page > table.getTotalPages() ){
				System.out.println("无效的页码 "+input_page);
			}
			else{
				page = input_page;
			}
		}
		if (page > 0) //页码改变，发一个通知
		{
			PageChangeEvent evt = new PageChangeEvent(table);
			evt.setPageNumber(page);
			evt.setPhaseId(PhaseId.INVOKE_APPLICATION);
			table.queueEvent(evt);
		}
	}
	private String getFormId(UIComponent component, FacesContext context) throws IOException {
		UIComponent parent = component.getParent();
		while ((parent != null) && !(parent instanceof UIForm))
			parent = parent.getParent();
		if (parent == null)
			throw new IOException("DS command link must be in a form");
		
		return ((UIForm)parent).getClientId(context);
	}

	private Table findTableFor(FacesContext context, UIComponent component) {
		assert (component instanceof DataScroller);
		DataScroller ds = (DataScroller) component;
		String specified_table = ds.getTableFor();
		if(specified_table == null)
		{
			UIComponent parent = component.getParent();
			while (parent!= null && !(parent instanceof Table))
					parent = parent.getParent();
			
			return (Table) parent;
		}
		else{
			
			UIComponent c= component.getParent().findComponent(specified_table);
			if (c instanceof Table)
				return (Table) c;
			else
				return null;
		}
		
	}
	@Override
	public void encodeEnd(FacesContext context, UIComponent component)
			throws IOException {
		assert (component instanceof DataScroller);
		DataScroller ds = (DataScroller) component;
		String specified_table = ds.getTableFor();
		ResponseWriter writer = context.getResponseWriter();
		if (specified_table == null)
		{
			writer.endElement("td");
			writer.endElement("tr");
		}
		else
		{
			writer.endElement("p");
		}
	}
}
